#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ESLint 插件
用于 JavaScript/TypeScript 代码检查
"""

import os
import subprocess
import json
from typing import Dict, List, Any


class ESLintPlugin:
    """ESLint 插件"""
    
    def __init__(self):
        self.name = "eslint"
        self.description = "JavaScript/TypeScript 代码检查"
    
    def execute(self, config: Dict[str, Any], context: Dict[str, Any]) -> Dict[str, Any]:
        """执行 ESLint 检查"""
        try:
            # 获取配置参数
            files = config.get('files', [])
            options = config.get('options', [])
            config_file = config.get('config_file')
            fix = config.get('fix', False)
            
            # 构建命令
            cmd = ['npx', 'eslint']
            
            # 添加配置文件
            if config_file and os.path.exists(config_file):
                cmd.extend(['--config', config_file])
            
            # 添加选项
            if options:
                cmd.extend(options)
            
            # 添加修复选项
            if fix:
                cmd.append('--fix')
            
            # 添加文件
            if files:
                cmd.extend(files)
            else:
                # 如果没有指定文件，检查暂存文件
                staged_files = context.get('staged_files', [])
                js_files = [f for f in staged_files if f.endswith(('.js', '.ts', '.jsx', '.tsx'))]
                if js_files:
                    cmd.extend(js_files)
                else:
                    return {
                        'success': True,
                        'output': '没有需要检查的 JavaScript/TypeScript 文件',
                        'exit_code': 0
                    }
            
            # 执行命令
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                timeout=300
            )
            
            # 解析结果
            output_lines = result.stdout.split('\n') if result.stdout else []
            error_lines = result.stderr.split('\n') if result.stderr else []
            
            # 检查是否有错误
            has_errors = result.returncode != 0
            
            # 格式化输出
            if has_errors:
                formatted_output = self._format_eslint_output(output_lines, error_lines)
                return {
                    'success': False,
                    'output': formatted_output,
                    'error': '\n'.join(error_lines),
                    'exit_code': result.returncode
                }
            else:
                return {
                    'success': True,
                    'output': 'ESLint 检查通过',
                    'exit_code': 0
                }
                
        except subprocess.TimeoutExpired:
            return {
                'success': False,
                'output': '',
                'error': 'ESLint 执行超时',
                'exit_code': 1
            }
        except Exception as e:
            return {
                'success': False,
                'output': '',
                'error': f'ESLint 执行失败: {e}',
                'exit_code': 1
            }
    
    def _format_eslint_output(self, output_lines: List[str], error_lines: List[str]) -> str:
        """格式化 ESLint 输出"""
        formatted = []
        
        for line in output_lines:
            if line.strip():
                # 解析 ESLint 输出格式
                if ':' in line:
                    parts = line.split(':', 3)
                    if len(parts) >= 4:
                        file_path = parts[0]
                        line_num = parts[1]
                        col_num = parts[2]
                        message = parts[3].strip()
                        
                        formatted.append(f"  {file_path}:{line_num}:{col_num} - {message}")
                    else:
                        formatted.append(f"  {line}")
                else:
                    formatted.append(f"  {line}")
        
        if error_lines:
            formatted.append("\n错误信息:")
            for line in error_lines:
                if line.strip():
                    formatted.append(f"  {line}")
        
        return '\n'.join(formatted)
    
    def check_installation(self) -> bool:
        """检查 ESLint 是否已安装"""
        try:
            result = subprocess.run(
                ['npx', 'eslint', '--version'],
                capture_output=True,
                text=True,
                timeout=10
            )
            return result.returncode == 0
        except Exception:
            return False
    
    def install_eslint(self, project_dir: str = None) -> bool:
        """安装 ESLint"""
        try:
            cmd = ['npm', 'install', '--save-dev', 'eslint']
            if project_dir:
                result = subprocess.run(cmd, cwd=project_dir, timeout=60)
            else:
                result = subprocess.run(cmd, timeout=60)
            
            return result.returncode == 0
        except Exception:
            return False
    
    def create_config(self, config_file: str = '.eslintrc.js') -> bool:
        """创建 ESLint 配置文件"""
        try:
            config_content = '''module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true
  },
  extends: [
    'eslint:recommended'
  ],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module'
  },
  rules: {
    'no-unused-vars': 'warn',
    'no-console': 'warn',
    'semi': ['error', 'always'],
    'quotes': ['error', 'single']
  }
};
'''
            
            with open(config_file, 'w', encoding='utf-8') as f:
                f.write(config_content)
            
            return True
        except Exception:
            return False


# 插件接口
def execute(config: Dict[str, Any], context: Dict[str, Any]) -> Dict[str, Any]:
    """插件执行接口"""
    plugin = ESLintPlugin()
    return plugin.execute(config, context)


if __name__ == "__main__":
    # 测试插件
    plugin = ESLintPlugin()
    
    # 测试配置
    test_config = {
        'files': ['test.js'],
        'options': ['--format', 'compact']
    }
    
    test_context = {
        'staged_files': ['test.js', 'test.ts']
    }
    
    result = plugin.execute(test_config, test_context)
    print(f"执行结果: {result}")
